package com.tengju.support.domain.model.rule;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.google.common.collect.Lists;
import com.tengju.support.domain.shared.DomainException;
import com.tengju.support.domain.shared.DomainExceptionCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;

@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@Clazz")
public class Condition {

    LogicalOperator operator;

    List<Condition> child;


    @JsonProperty(value = "@Clazz")
    String getClazz() {
        return this.getClass().getName();
    };

    /**
     * 创建全匹配条件
     */
    public static Condition createFullMatchCondition(List<ConditionForm> forms) {

        if (CollectionUtils.isEmpty(forms)) {
            throw DomainException.error(DomainExceptionCode.INVALID_DATA,"创建condition失败");
        }

        if (forms.size() == 1) {
            //叶子节点 创建对应类型的condition
            ConditionForm conditionForm = forms.get(0);
            ConditionType type = ConditionType
                    .parseByOperation(conditionForm.getOperation());
            Condition leafCondition;

            try {
                Class<?> conditionClass = Class.forName(type.getClassPath());
                Constructor<?> constructor = conditionClass.getConstructor(String.class, List.class, Operation.class);
                leafCondition = (Condition)constructor.newInstance(conditionForm.getField(), conditionForm.getFactors(), conditionForm.getOperation());
            } catch (Exception e) {
                log.error("创建叶子节点condition失败",e);
                throw DomainException.error(DomainExceptionCode.INVALID_DATA,"创建叶子节点condition失败");
            }

            return leafCondition;

        } else {
            //非叶子节点 递归
            List<ConditionForm> childForm1 = forms.subList(0, 1);
            List<ConditionForm> childForm2 = forms.subList(1, forms.size());
            Condition childCondition1 = createFullMatchCondition(childForm1);
            Condition childCondition2 = createFullMatchCondition(childForm2);

            List<Condition> child = Lists.newArrayList();
            child.add(childCondition1);
            child.add(childCondition2);

            return new Condition(LogicalOperator.AND,child);

        }

    }



    /**
     * 执行condition条件判断
     */
    public boolean evaluate(MetaInfo metaInfo) {
        if (child.size() == 2){
            //非叶子节点 用与或逻辑符连接
            switch (operator) {
                case AND:
                    return child.get(0).evaluate(metaInfo) && child.get(1).evaluate(metaInfo);
                case OR:
                    return child.get(0).evaluate(metaInfo) || child.get(1).evaluate(metaInfo);
                default:
                    return false;
            }
        } else {
            throw DomainException.error(DomainExceptionCode.INVALID_DATA,"条件格式错误");
        }
    }

    /**
     * 反射 获取field字段的值
     */
    public Object fieldData(MetaInfo metaInfo,String field) {
        Field declaredField;
        try {
            declaredField = metaInfo.getClass().getDeclaredField(field);
            declaredField.setAccessible(true);
            return declaredField.get(metaInfo);
        } catch (Exception e) {
            throw DomainException.error(DomainExceptionCode.RULE_FACT_ERROR);
        }

    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        UserMetaInfo userMetaInfo = new UserMetaInfo();
        Field declaredField = userMetaInfo.getClass().getDeclaredField("starLevel");
        declaredField.setAccessible(true);
        Object o = declaredField.get(userMetaInfo);
        String s = String.valueOf(o);
        System.out.println(s);
    }

}
